home *** CD-ROM | disk | FTP | other *** search
- unit Basmu;
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, ExtCtrls, StdCtrls;
-
- type
- TBIOSCounterForm = class(TForm)
- Label1: TLabel;
- Label2: TLabel;
- procedure FormActivate(Sender: TObject);
- private
- { Stores a copy of the BIOS timer counter }
- FBIOSCounter: Longint;
- { Updates FBIOSCounter }
- function GetBIOSCounter: Longint;
- public
- { Simple property to set up and return FBIOSCounter }
- property BIOSCounter: Longint read GetBIOSCounter;
- end;
-
- var
- BIOSCounterForm: TBIOSCounterForm;
-
- implementation
-
- {$R *.DFM}
-
- const
- { You really shouldn't do this - i.e. use a hard-coded segment number }
- { in Windows as segments don't exist, only selectors which you need to }
- { obtain via Windows or DPMI calls. However, in Windows 3.x, selector }
- { $40 is coded to be a match for segment $40, the BIOS Data Area }
- BIOSArea = $40;
- BIOSCounterLo = $6C;
- BIOSCounterHi = $6E;
-
- {$define VERSION1}
-
- {$ifdef VERSION1}
- function TBIOSCounterForm.GetBIOSCounter: Longint;
- begin
- FBIOSCounter := MemL[BIOSArea:BIOSCounterLo];
- Result := FBIOSCounter;
- end;
- {$endif}
-
- {$ifdef VERSION2}
- function TBIOSCounterForm.GetBIOSCounter: Longint;
- begin
- LongRec(FBIOSCounter).Lo := MemW[BIOSArea:BIOSCounterLo];
- LongRec(FBIOSCounter).Hi := MemW[BIOSArea:BIOSCounterHi];
- Result := FBIOSCounter;
- end;
- {$endif}
-
- {$ifdef VERSION3}
- function TBIOSCounterForm.GetBIOSCounter: Longint;
- begin
- WordRec(LongRec(FBIOSCounter).Lo).Lo := Mem[BIOSArea:BIOSCounterLo];
- WordRec(LongRec(FBIOSCounter).Lo).Hi := Mem[BIOSArea:Succ(BIOSCounterLo)];
- WordRec(LongRec(FBIOSCounter).Hi).Lo := Mem[BIOSArea:BIOSCounterHi];
- WordRec(LongRec(FBIOSCounter).Hi).Hi := Mem[BIOSArea:Succ(BIOSCounterHi)];
- Result := FBIOSCounter;
- end;
- {$endif}
-
- {$ifdef VERSION4}
- function TBIOSCounterForm.GetBIOSCounter: Longint; assembler;
- asm
- mov ax, BIOSArea
- mov es, ax
- mov di, BIOSCounterLo
- { Longint's are returned in DX:AX }
- { AX is the low result word }
- mov ax, es:[di]
- mov di, BIOSCounterHi
- { DX is the high result word }
- mov dx, es:[di]
- les di, Self
- { Having loaded the reference to this form in ES:DI, we need to access }
- { its FBIOSCounter field. We then need to store AX in its low word. }
- { After that we get the high BIOS timer counter word and do the same thing }
- { but store AX in the high word. An example of a statement that does this is: }
- { mov TBIOSCounterForm(es:[di]).FBIOSCounter.Word[0], ax }
- { We can consider this split into two parts. The part that references the }
- { field of interest, i.e. structured variable access, and the part that }
- { accesses the relevant word of the field, i.e. unstructured variable }
- { access. The structured variable access can be written in these ways: }
- { TBIOSCounterForm(es:[di]).FBIOSCounter }
- { TBIOSCounterForm[es:di].FBIOSCounter }
- { TBIOSCounterForm([es:di]).FBIOSCounter }
- { (TBIOSCounterForm ptr es:[di]).FBIOSCounter }
- { (TBIOSCounterForm ptr [es:di]).FBIOSCounter }
- { ([TBIOSCounterForm ptr es:di]).FBIOSCounter }
- { es:TBIOSCounterForm[di].FBIOSCounter }
- { es:TBIOSCounterForm([di]).FBIOSCounter }
- { es:[di].TBIOSCounterForm.FBIOSCounter }
- { [es:di].TBIOSCounterForm.FBIOSCounter }
- { The unstructured variable access can be written in many different ways: }
- { (the *'d formats are valid if you are accessing only the first bytes) }
- { LongRec(structured_part).Lo }
- { * Word(structured_part) }
- { * structured_part.Word }
- { structured_part.Word.0 }
- { structured_part.Word[0] }
- { * word ptr structured_part }
- { * word ptr [structured_part] }
- { word ptr structured_part + 0 }
- { word ptr [structured_part] + 0 }
- { word ptr [structured_part + 0] }
- { So, to get to the low and high word of this field }
- { the following two lines are valid possibilities }
- mov word ptr [(TBIOSCounterForm ptr es:[di]).FBIOSCounter] + 0, ax
- mov es:[di].TBIOSCounterForm.FBIOSCounter.Word.2, dx
- end;
- {$endif}
-
- procedure TBIOSCounterForm.FormActivate(Sender: TObject);
- begin
- repeat
- Application.ProcessMessages;
- Label1.Caption := IntToStr(BIOSCounter);
- until Application.Terminated;
- end;
-
- end.
-